import _ from 'lodash'
import { article, section } from './lablog.js'
const log = console.log
const {curry, curryRight, flowRight} = _
article("组合：选择几个函数让他们结合产生新的函数")


const toUpperCase = x => {
    console.log("to UpperCase")
    return x.toUpperCase()
}
const exclaim = x => {
    console.log("exclaim executed!")
    return x + "!"
}
const shout = flowRight(exclaim, toUpperCase)
log(shout("cherry"))

section("结合律的一大好处是任何一个函数分组都可以被拆开来，然后再以它们自己的组合方式打包在一起。")

section("pointfree: 永远不必说出你的数据。函数无须提及将要操作的数据是什么样的。一等公民的函数、柯里化以及组合协作起来非常有助于实现这种模式")

// 非 pointfree,因为提到了数据 word
const snakeCase = function(word) {
    return word.toLowerCase().replace(/\s+/ig, '_')
}
log("non pointfree snake_case:", snakeCase("hello point Free."))

// log(_.replace("hello world with loadash.replace", /\s+/ig, '_'))
const replaceStr = (initial, reg, replacement) => _.replace(initial, reg, replacement)
const replace = curryRight(replaceStr)
const snake_case = flowRight(replace(/\s+/ig, '_'), _.lowerCase)
log("pointfree snake_case:", snake_case("hello point Free."))

section("另外，pointfree 能够帮助我们减少不必要的命名，让代码保持简洁和通用。不过你也要注意并非所有的函数式代码都是 pointfree 的，可以使用的时候就用，不能用的时候就使用普通函数。")

section("组合像一系列管道那样将不同的函数联系在一起，数据就可以在其中流动。")
section("我们认为组合是高于其他所有原则的设计原则，这是因为组合让我们代码简单且富有可读性。")
section("另外，范畴学在应用架构、模拟副作用和保证正确性方面扮演重要角色")